/**
  ******************************************************************************
  * @file 
  * @brief 
  * @author Moon
  * @version V1.0.0
  * @date 2022/09/18
  ******************************************************************************
  */
#include "communication.h"
#include "drv_f4_can.h"
#include "A_aclass_protocol.h"
#include "lwip_app.h"
#include "version.h"
#include "cmd_process.h"
#include "calibrate_dac_task.h"
#include "drv_f4_usart.h"
/* private config -----------------------------------------------------------*/

/* Public defines -----------------------------------------------------------*/

/* Public enum    -----------------------------------------------------------*/

/* Public Struct  -----------------------------------------------------------*/
uint32_t uart_hardname;
uint8_t firstAclassReg=1;
static int Aclass_register(void);
static int Aclass_register_uart(void);
static void tcp_senddata_callback(uint8_t addr, char *data, uint32_t len);
ack_packet_t *shell_callback  ( user_packet_t * user );
static void UsartRecvMsg(uint8_t *buf, uint32_t len);
static void Usart_senddata_callback(uint8_t addr, char *data, uint32_t len);
//Pointer

//Array

//Const
drv_usart_t  comm=
{
    .Drv_Num = "UART4",//"USART2",              
    .Tx_Pin = "A0",
    .Rx_Pin = "A1",
    .BaudRate = 115200,
    .WordLength = USART_WORDLENGTH_8BIT,
    .StopBits = USART_STOPBITS_1BIT,
    .Parity = USART_PARITY_NO,
	.dma_buffer_size=1200,
	.arg=NULL,
    .Rx_Priority = 10,
	.Idle_CallBack = UsartRecvMsg,
};
/***********************************************************************************
 * @brief   Usart接收数据
 * ex:      
* @par     输入参数：void * arg - 输入硬件名称
 *                   uint8_t *buf - 接收到的数据
 *                   uint32_t len - 接收到的数据长度
 *         输出参数：无
 * None
 * @retval 返回值：无
 **********************************************************************************/
static void UsartRecvMsg(uint8_t *buf, uint32_t len)
{
    Aclass_CmdReceive_Notify("Usart", 1, buf, len, IN_INT);   //hard_name,phyaddr,buff,len,irq
    
}

/***********************************************************************************
 * @brief Usart口发送回调
 * ex:
 * @par    None
 * @retval None
 **********************************************************************************/
static void Usart_senddata_callback(uint8_t addr, char *data, uint32_t len)
{
    taskENTER_CRITICAL();
    comm.Write(&comm, (uint8_t *)data, (uint32_t)len);
    taskEXIT_CRITICAL();
}

/***********************************************************************************
 * @brief   通信初始化
 * ex:      
 * @par 
 * None
 * @retval void None
 **********************************************************************************/
void communication_init(void)
{
//	uint8_t Shakehand[15] =  {0xA1,0x00,0x08,0x00,0x01,0x51,0x00,0x02,0x00};
//	uint8_t WorkspaceW[15] = {0xA1,0x00,0x09,0x00,0x01,0x53,0x00,0x05,0x00,0x01};
//	uint8_t WorkspaceR[15] = {0xA1,0x00,0x08,0x00,0x01,0x51,0x00,0x05,0x00};
//	Crc16_Rtu_Create((unsigned char *)Shakehand, 11, 0);
//	Crc16_Rtu_Create((unsigned char *)WorkspaceW, 12, 0);
//	Crc16_Rtu_Create((unsigned char *)WorkspaceR, 11, 0);
	
    LWIP_App_Init();
    Aclass_Protocol_Init(Aclass_register);        //设置TCP通信命令与响应函数链表
	
    const char * hard_name="Usart";
    uart_hardname = String_To_Crc32(hard_name);
	if (Drv_Usart_Init(&comm) != 0)
	{
       while (1);
	}
    Aclass_Protocol_Init(Aclass_register_uart);   //设置串口通信命令与响应函数链表
}

/***********************************************************************************
 * @brief  功能说明：设置TCP发送指令、接收指令的响应函数链表
 * ex:
 * @par    输入参数：无
 *         输出参数：无
 * @retval 返回值：默认返回0
 **********************************************************************************/
static int Aclass_register(void)
{
    uint8_t parent_id = 0, g_dev_id = 0;
	
	g_dev_id = atoi(ACLASS_ID);
	
    //Apara_Read("ParInfo", &parent_id, sizeof(uint8_t));
    Aclass_SET_LocalSoftID(g_dev_id);
	
    Aclass_Hardware_Register("tcp", tcp_senddata_callback, NULL);
	Aclass_Node_Register("PC", "tcp", PARENT_NODE, parent_id, parent_id);   //tcp没有ID随意
    
	Aclass_Send_Register("motor", "PC", DATA_HEAD, BURST_SEND, 0x03, 0x0a, 0);
	Aclass_Send_Register("monitor", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x45, 0);
	Aclass_Send_Register("pres", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x3e, 0);
	Aclass_Send_Register("inf_pum", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x46, 0);
	Aclass_Send_Register("detect", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x48, 0);
	//Aclass_Send_Register("complete_temp_cali", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x50, 0);
    Aclass_Send_Register("cali_provalve_state", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x52, 0);
    Aclass_Send_Register("upload_base_cbm", "PC",DATA_HEAD, BURST_SEND,0x04,0x53,0);

    
	// BR cmd
	Aclass_Cmd_Register(0x00, 0x01, Version_callback);   //0x00, 0x01对应协议命令,子命令
	Aclass_Cmd_Register(0x00, 0x02, Shakehand_callback);
	Aclass_Cmd_Register(0x00, 0x03, Selfcheck_callback);
	Aclass_Cmd_Register(0x00, 0x04, Cputem_callback);
	Aclass_Cmd_Register(0x00, 0x05, Workspace_callback);
	Aclass_Cmd_Register(0x00, 0x06, Deviceinf_callback);
	Aclass_Cmd_Register(0x00, 0x07, Serial_num_callback);
	Aclass_Cmd_Register(0x00, 0x09, Reboot_callback);
	Aclass_Cmd_Register(0x00, 0x0A, Check_time_callback);
	Aclass_Cmd_Register(0x00, 0x0B, Read_Fram_callback);
	//Aclass_Cmd_Register(0x00, 0x10, shell_callback);
	
	Aclass_Cmd_Register(0x01, 0x01, dhcp_switch_callback);
	Aclass_Cmd_Register(0x01, 0x02, local_ip_callback);
	Aclass_Cmd_Register(0x01, 0x03, local_port_callback);
	Aclass_Cmd_Register(0x01, 0x04, gateway_callback);
	Aclass_Cmd_Register(0x01, 0x05, netmark_callback);
	Aclass_Cmd_Register(0x01, 0x06, mac_callback);
	Aclass_Cmd_Register(0x01, 0x61, network_par_callback);
	
	/* 校准 */
	Aclass_Cmd_Register(0x02, 0x01, cail_dac_callback); 
	Aclass_Cmd_Register(0x02, 0x02, cail_tempAdc_callback);
	Aclass_Cmd_Register(0x02, 0x03, cail_presAdc_callback);
	Aclass_Cmd_Register(0x02, 0x04, cail_preS1_callback);
	Aclass_Cmd_Register(0x02, 0x05, cail_preS2_callback);
	Aclass_Cmd_Register(0x02, 0x06, cail_preS3_callback);
	Aclass_Cmd_Register(0x02, 0x07, cail_preP0_callback);
	Aclass_Cmd_Register(0x02, 0x08, cail_preAmber_callback);
    
	/* 控制 */
	Aclass_Cmd_Register(0x03, 0x01, ctrl_mode_callback);
	Aclass_Cmd_Register(0x03, 0x02, ctrl_process_callback);
	Aclass_Cmd_Register(0x03, 0x03, ctrl_devtime_callback);
	Aclass_Cmd_Register(0x03, 0x04, ctrl_readadc_callback);
	Aclass_Cmd_Register(0x03, 0x05, ctrl_setdac_callback);
	Aclass_Cmd_Register(0x03, 0x06, ctrl_start_callback);
	Aclass_Cmd_Register(0x03, 0x07, ctrl_motor_callback);
	Aclass_Cmd_Register(0x03, 0x0a, ctrl_readmotor_callback);
	Aclass_Cmd_Register(0x03, 0x0b, ctrl_led_seterror_callback);
    Aclass_Cmd_Register(0x03, 0x0c, ctrl_led_restore_callback);
    
	Aclass_Cmd_Register(0x04, 0x01, pres_pumpSwitch_callback);
	Aclass_Cmd_Register(0x04, 0x02, pres_valveSwitch_callback);
	Aclass_Cmd_Register(0x04, 0x03, pres_setpres1_callback);
	Aclass_Cmd_Register(0x04, 0x04, pres_setpres2_callback);
	Aclass_Cmd_Register(0x04, 0x05, pres_setpres3_callback);
	Aclass_Cmd_Register(0x04, 0x06, pres_setpres4_callback);
	Aclass_Cmd_Register(0x04, 0x07, pres_setpres5_callback);
	
	Aclass_Cmd_Register(0x04, 0x0d, pres_readpres1_callback);
	Aclass_Cmd_Register(0x04, 0x0e, pres_readpres2_callback);
	Aclass_Cmd_Register(0x04, 0x0f, pres_readpres3_callback);
	Aclass_Cmd_Register(0x04, 0x10, pres_readpres4_callback);
	Aclass_Cmd_Register(0x04, 0x11, pres_readpres5_callback);
	
	Aclass_Cmd_Register(0x04, 0x17, pres_state_callback);
	
	Aclass_Cmd_Register(0x04, 0x21, pres_setprovalve_callback);
	
	Aclass_Cmd_Register(0x04, 0x23, pres_tolerance1_callback);
	Aclass_Cmd_Register(0x04, 0x24, pres_tolerance2_callback);
	Aclass_Cmd_Register(0x04, 0x25, pres_tolerance3_callback);
	Aclass_Cmd_Register(0x04, 0x26, pres_tolerance4_callback);
	Aclass_Cmd_Register(0x04, 0x27, pres_tolerance5_callback);
	
	Aclass_Cmd_Register(0x04, 0x2d, pres_pidcycle_callback);
	Aclass_Cmd_Register(0x04, 0x32, pres_pid_callback);
	
	Aclass_Cmd_Register(0x04, 0x33, pres_temp1_callback); // used only.
	Aclass_Cmd_Register(0x04, 0x34, pres_temp2_callback); // reserved.
	Aclass_Cmd_Register(0x04, 0x35, pres_temp3_callback); // reserved.
	
	Aclass_Cmd_Register(0x04, 0x3D, pres_ctrl_callback);
	Aclass_Cmd_Register(0x04, 0x3F, pres_gas_callback);  	
	
	Aclass_Cmd_Register(0x04, 0x49, valve_pulse_ctrl_callback); 
	Aclass_Cmd_Register(0x04, 0x4a, provalve_ctrl_callback); 
	
	Aclass_Cmd_Register(0x04, 0x4b, cal_press_b_ctrl_callback); 
	Aclass_Cmd_Register(0x04, 0x4c, cal_press_match_b_ctrl_callback); 
	Aclass_Cmd_Register(0x04, 0x4d, cal_press_k_ctrl_callback); 
	Aclass_Cmd_Register(0x04, 0x4e, provalve_close_callback);
	Aclass_Cmd_Register(0x04, 0x4f, record_res_value_ctrl_callback);
	
    Aclass_Cmd_Register(0x04, 0x50, cail_provalve_callback);
    
	Aclass_Cmd_Register(0x04, 0x53, record_base_cbm_ctrl_callback);
	Aclass_Cmd_Register(0x04, 0x54, pres_valveSwitch_New_callback);
	Aclass_Cmd_Register(0x04, 0x55, pres_stop_infpum_callback);
    
	
    //A_table_protocol_init();
    return 0;
}

/***********************************************************************************
 * @brief  功能说明：设置串口发送指令、接收指令的响应函数链表
 * ex:
 * @par    输入参数：无
 *         输出参数：无
 * @retval 返回值：默认返回0
 **********************************************************************************/
extern void Aclass_Protocol_UART_Task(void *pvParameters);
static int Aclass_register_uart(void)
{
    uint8_t parent_id = 0, g_dev_id = 1;
    //Apara_Read("ParInfo", &parent_id, sizeof(uint8_t));
    xTaskCreate(Aclass_Protocol_UART_Task, "Aclass_Protocol_UART_Task",
            A_PROTOCOL_TASK_SIZE, NULL, A_PROTOCOL_TASK_PRIORITY, 0);
    
    
    Aclass_SET_LocalSoftID(g_dev_id);
    
    Aclass_Hardware_Register("Usart", Usart_senddata_callback, NULL);
    Aclass_Node_Register("UA", "Usart", PARENT_NODE, 1, 1);
    
	// BR cmd
//	Aclass_Send_Register("motor", "PC", DATA_HEAD, BURST_SEND, 0x03, 0x0a, 0);
//	Aclass_Send_Register("monitor", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x45, 0);
//	Aclass_Send_Register("pres", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x3e, 0);
//	Aclass_Send_Register("inf_pum", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x46, 0);
//	Aclass_Send_Register("detect", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x48, 0);
//	Aclass_Send_Register("complete_temp_cali", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x50, 0);
//  Aclass_Send_Register("cali_provalve_state", "PC", DATA_HEAD, BURST_SEND, 0x04, 0x51, 0);
	
	Aclass_Cmd_Register(0x00, 0x01, Version_callback);   //0x00, 0x01对应协议命令,子命令
	Aclass_Cmd_Register(0x00, 0x02, Shakehand_callback);
	Aclass_Cmd_Register(0x00, 0x03, Selfcheck_callback);
	Aclass_Cmd_Register(0x00, 0x04, Cputem_callback);
	Aclass_Cmd_Register(0x00, 0x05, Workspace_callback);
	Aclass_Cmd_Register(0x00, 0x06, Deviceinf_callback);
	Aclass_Cmd_Register(0x00, 0x07, Serial_num_callback);
	Aclass_Cmd_Register(0x00, 0x09, Reboot_callback);
	Aclass_Cmd_Register(0x00, 0x0A, Check_time_callback);
	Aclass_Cmd_Register(0x00, 0x0B, Read_Fram_callback);
	//Aclass_Cmd_Register(0x00, 0x10, shell_callback);
	
	Aclass_Cmd_Register(0x01, 0x01, dhcp_switch_callback);
	Aclass_Cmd_Register(0x01, 0x02, local_ip_callback);
	Aclass_Cmd_Register(0x01, 0x03, local_port_callback);
	Aclass_Cmd_Register(0x01, 0x04, gateway_callback);
	Aclass_Cmd_Register(0x01, 0x05, netmark_callback);
	Aclass_Cmd_Register(0x01, 0x06, mac_callback);
	Aclass_Cmd_Register(0x01, 0x61, network_par_callback);
	
	/* 校准 */
	Aclass_Cmd_Register(0x02, 0x01, cail_dac_callback); 
	Aclass_Cmd_Register(0x02, 0x02, cail_tempAdc_callback);
	Aclass_Cmd_Register(0x02, 0x03, cail_presAdc_callback);
	Aclass_Cmd_Register(0x02, 0x04, cail_preS1_callback);
	Aclass_Cmd_Register(0x02, 0x05, cail_preS2_callback);
	Aclass_Cmd_Register(0x02, 0x06, cail_preS3_callback);
	Aclass_Cmd_Register(0x02, 0x07, cail_preP0_callback);
	Aclass_Cmd_Register(0x02, 0x08, cail_preAmber_callback);
    
	/* 控制 */
	Aclass_Cmd_Register(0x03, 0x01, ctrl_mode_callback);
	Aclass_Cmd_Register(0x03, 0x02, ctrl_process_callback);
	Aclass_Cmd_Register(0x03, 0x03, ctrl_devtime_callback);
	Aclass_Cmd_Register(0x03, 0x04, ctrl_readadc_callback);
	Aclass_Cmd_Register(0x03, 0x05, ctrl_setdac_callback);
	Aclass_Cmd_Register(0x03, 0x06, ctrl_start_callback);
	Aclass_Cmd_Register(0x03, 0x07, ctrl_motor_callback);
	Aclass_Cmd_Register(0x03, 0x0a, ctrl_readmotor_callback);
    
    Aclass_Cmd_Register(0x03, 0x12, ctrl_backfill_callback);
    
	
	Aclass_Cmd_Register(0x04, 0x01, pres_pumpSwitch_callback);
	Aclass_Cmd_Register(0x04, 0x02, pres_valveSwitch_callback);
	Aclass_Cmd_Register(0x04, 0x03, pres_setpres1_callback);
	Aclass_Cmd_Register(0x04, 0x04, pres_setpres2_callback);
	Aclass_Cmd_Register(0x04, 0x05, pres_setpres3_callback);
	Aclass_Cmd_Register(0x04, 0x06, pres_setpres4_callback);
	Aclass_Cmd_Register(0x04, 0x07, pres_setpres5_callback);
	
	Aclass_Cmd_Register(0x04, 0x0d, pres_readpres1_callback);
	Aclass_Cmd_Register(0x04, 0x0e, pres_readpres2_callback);
	Aclass_Cmd_Register(0x04, 0x0f, pres_readpres3_callback);
	Aclass_Cmd_Register(0x04, 0x10, pres_readpres4_callback);
	Aclass_Cmd_Register(0x04, 0x11, pres_readpres5_callback);
	
	Aclass_Cmd_Register(0x04, 0x17, pres_state_callback);
	
	Aclass_Cmd_Register(0x04, 0x21, pres_setprovalve_callback);
	
	Aclass_Cmd_Register(0x04, 0x23, pres_tolerance1_callback);
	Aclass_Cmd_Register(0x04, 0x24, pres_tolerance2_callback);
	Aclass_Cmd_Register(0x04, 0x25, pres_tolerance3_callback);
	Aclass_Cmd_Register(0x04, 0x26, pres_tolerance4_callback);
	Aclass_Cmd_Register(0x04, 0x27, pres_tolerance5_callback);
	
	Aclass_Cmd_Register(0x04, 0x2d, pres_pidcycle_callback);
	Aclass_Cmd_Register(0x04, 0x32, pres_pid_callback);
	
	Aclass_Cmd_Register(0x04, 0x33, pres_temp1_callback); // used only.
	Aclass_Cmd_Register(0x04, 0x34, pres_temp2_callback); // reserved.
	Aclass_Cmd_Register(0x04, 0x35, pres_temp3_callback); // reserved.
	
	Aclass_Cmd_Register(0x04, 0x3D, pres_ctrl_callback);
	Aclass_Cmd_Register(0x04, 0x3F, pres_gas_callback);  	
	
	Aclass_Cmd_Register(0x04, 0x49, valve_pulse_ctrl_callback); 
	Aclass_Cmd_Register(0x04, 0x4a, provalve_ctrl_callback); 
	
	Aclass_Cmd_Register(0x04, 0x4b, cal_press_b_ctrl_callback); 
	Aclass_Cmd_Register(0x04, 0x4c, cal_press_match_b_ctrl_callback); 
	Aclass_Cmd_Register(0x04, 0x4d, cal_press_k_ctrl_callback); 
	Aclass_Cmd_Register(0x04, 0x4e, provalve_close_callback);
	Aclass_Cmd_Register(0x04, 0x4f, record_res_value_ctrl_callback);
	
    Aclass_Cmd_Register(0x04, 0x50, cail_provalve_callback);
    
	Aclass_Cmd_Register(0x04, 0x54, pres_valveSwitch_New_callback);    
    return 0;
}

/***********************************************************************************
 * @brief shell输入
 * ex:
 * @par
 * None
 * @retval 应答数据包首地址
 **********************************************************************************/
ack_packet_t *shell_callback  ( user_packet_t * user )
{
    ack_packet_t *ack;

    // 应答返回数据
    ack = Ack_Malloc(0);
//	Ashell_rx_callback(user->data, user->len);
	
	return ack;    
}

/***********************************************************************************
 * @brief tcp发送回调
 * ex:
 * @par    None
 * @retval None
 **********************************************************************************/
static void tcp_senddata_callback(uint8_t addr, char *data, uint32_t len)
{
	tcp_senddata((uint8_t *)data, (uint32_t)len);
}

